<?php
/**
 * Created by PhpStorm.
 * User: yf
 * Date: 2018/1/9
 * Time: 下午1:04.
 */

namespace EasySwoole;

use App\Process\GameTurn;
use App\Process\Heartbeat;
use EasySwoole\Core\AbstractInterface\EventInterface;
use EasySwoole\Core\Component\Crontab\CronTab;
use EasySwoole\Core\Swoole\ServerManager;
use EasySwoole\Core\Swoole\EventRegister;
use EasySwoole\Core\Http\Request;
use EasySwoole\Core\Http\Response;
use EasySwoole\Core\Swoole\Process\ProcessManager;
use EasySwoole\Core\Utility\File;
use App\Sock\Parser\WebSock;
use EasySwoole\Core\Swoole\EventHelper;
use EasySwoole\Core\Component\Di;
use App\Utility\Redis;
use App\Sock\Logic\Game;
use App\Process\Inotify;
use App\Process\OpenLottery;
use App\Process\RefreshCache;
use App\Process\GameRound;

class EasySwooleEvent implements EventInterface
{
    public static function frameInitialize(): void
    {
        // TODO: Implement frameInitialize() method.
        date_default_timezone_set('Asia/Shanghai');
        // 批量载入配置文件
        self::loadConf(EASYSWOOLE_ROOT . '/Conf');

    }

    public static function mainServerCreate(ServerManager $server, EventRegister $register): void
    {

        $dbConf = Config::getInstance()->getConf('database');
        Di::getInstance()->set('MYSQL', \MysqliDb::class, Array(
                'host' => $dbConf['hostname'],
                'username' => $dbConf['username'],
                'password' => $dbConf['password'],
                'db' => $dbConf['database'],
                'port' => 3306,
                'charset' => 'utf8')
        );
        // 注册Redis放入容器
        $redis = new Redis(Config::getInstance()->getConf('redis'));
        Di::getInstance()->set('REDIS', $redis);

        // 注册Websocket服务
        EventHelper::registerDefaultOnMessage($register, WebSock::class);

//        CronTab::getInstance()->addRule()


        // ------------------------------------------------------------------------------------------
        ProcessManager::getInstance()->addProcess('autoReload', Inotify::class);
        ProcessManager::getInstance()->addProcess('Heartbeat', Heartbeat::class);
        ProcessManager::getInstance()->addProcess('GameRound',GameRound::class);
        ProcessManager::getInstance()->addProcess('OpenLottery', OpenLottery::class);
        ProcessManager::getInstance()->addProcess('RefreshCache', RefreshCache::class);



        CronTab::getInstance()->addRule('start', '00 00 * * *', function () {
            ProcessManager::getInstance()->writeByProcessName('RefreshCache', 'refresh');
        });

        $register->add($register::onHandShake, function (\swoole_http_request $request, \swoole_http_response $response) {
            if (0 === preg_match('#^[+/0-9A-Za-z]{21}[AQgw]==$#', $request->header['sec-websocket-key'])
                || 16 !== strlen(base64_decode($request->header['sec-websocket-key']))
            ) {
                //不接受握手
                var_dump('fail 1');
                $response->end();

                return false;
            }

            $key = base64_encode(sha1($request->header['sec-websocket-key'] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true));
            $headers = array(
                'Upgrade' => 'websocket',
                'Connection' => 'Upgrade',
                'Sec-WebSocket-Accept' => $key,
                'Sec-WebSocket-Version' => '13',
                'KeepAlive' => 'on',
            );
            foreach ($headers as $key => $val) {
                $response->header($key, $val);
            }
            //接受握手  发送验证后的header   还需要101状态码以切换状态
            $response->status(101);
            $response->end();
        });

        $register->add($register::onClose, function (\swoole_server $server, $fd, $reactorId) {
            // 检查是否是ws连接
            if (isset($server->connection_info($fd)['websocket_status']) && 3 === $server->connection_info($fd)['websocket_status']) {
                //清除Redis fd的全部关联
                Game::recyclingFd($fd);
            }
        });

        $register->add(EventRegister::onWorkerStart, function (\swoole_server $server, $workerId) {
            if ($workerId == 0) {
            }
        });
    }

    public static function onRequest(Request $request, Response $response): void
    {

//        $response->withHeader('Access-Control-Allow-Origin', '*');
//        $response->withHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
//        $response->withHeader('Access-Control-Allow-Credentials', 'true');
//        $response->withHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With');
//        if ($request->getMethod() === 'OPTIONS') {
//            $response->withStatus(Status::CODE_OK);
//            $response->end();
//        }
        // TODO: Implement onRequest() method.
    }

    public static function afterAction(Request $request, Response $response): void
    {
        // TODO: Implement afterAction() method.
    }

    public static function loadConf($ConfPath)
    {
        $Conf = Config::getInstance();
        $files = File::scanDir($ConfPath);
        foreach ($files as $file) {
            $data = require_once $file;
            $Conf->setConf(strtolower(basename($file, '.php')), (array)$data);
        }
    }
}
